﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WorkTool
{
    public partial class MainForm : Form
    {
        private JObject _swaggerData;
        private readonly HttpClient _httpClient;
        private List<TreeNode> _searchResults = new List<TreeNode>();
        private int _currentSearchIndex = -1;
        private string _lastSearchTerm = string.Empty;

        public MainForm()
        {
            InitializeComponent();

            // 初始化HttpClient并禁用SSL验证（用于本地开发）
            var handler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (_, _, _, _) => true
            };
            _httpClient = new HttpClient(handler);
        }

        #region tab1 Swagger分析器
        private async void btnLoad_Click(object sender, EventArgs e)
        {
            var swaggerUrl = txtUrl.Text.Trim();
            if (string.IsNullOrEmpty(swaggerUrl))
            {
                MessageBox.Show("请输入 Swagger URL", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                EnableLoadingUI(false);
                await LoadSwaggerJson(swaggerUrl);
                PopulateEndpointTree();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载 Swagger 数据失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Debug.WriteLine($"EXCEPTION: {ex}");
            }
            finally
            {
                EnableLoadingUI(true);
            }
        }

        /// <summary>
        /// 启用/禁用加载UI
        /// </summary>
        /// <param name="isEnabled"></param>
        private void EnableLoadingUI(bool isEnabled)
        {
            btnLoad.Enabled = isEnabled;
            btnGenerate.Enabled = isEnabled;
            treeEndpoints.Enabled = isEnabled;
            prgLoading.Visible = !isEnabled;
        }
        /// <summary>
        /// 加载Swagger JSON数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private async Task LoadSwaggerJson(string url)
        {
            var json = await _httpClient.GetStringAsync(url);
            _swaggerData = JObject.Parse(json);

            // 调试输出Swagger文档结构
            //Debug.WriteLine($"Swagger版本: {_swaggerData["swagger"] ?? _swaggerData["openapi"]}");
            //Debug.WriteLine($"路径数量: {((JObject)_swaggerData["paths"]).Count}");

            //// 检查一个示例路径
            //var firstPath = ((JObject)_swaggerData["paths"]).Properties().FirstOrDefault();
            //if (firstPath != null)
            //{
            //    Debug.WriteLine($"示例路径: {firstPath.Name}");
            //    Debug.WriteLine($"路径summary: {firstPath.Value["summary"]}");

            //    var firstMethod = ((JObject)firstPath.Value).Properties().FirstOrDefault(p =>
            //        p.Name != "summary" && p.Name != "description");
            //    if (firstMethod != null)
            //    {
            //        Debug.WriteLine($"示例方法: {firstMethod.Name}");
            //        Debug.WriteLine($"方法summary: {firstMethod.Value["summary"]}");
            //    }
            //}
        }

        /// <summary>
        /// 将Swagger文档中的API端点信息填充到树视图中
        /// </summary>
        /// <exception cref="InvalidOperationException"></exception>
        private void PopulateEndpointTree()
        {
            treeEndpoints.Nodes.Clear();

            if (_swaggerData?["paths"] is not JObject paths)
                throw new InvalidOperationException("未找到有效的API路径");

            // 创建标签分组字典
            var tagGroups = new Dictionary<string, TreeNode>();

            // 获取所有标签定义
            // 获取所有标签定义 - 增强版
            var tags = new JArray();

            // 尝试从根级别获取标签
            if (_swaggerData["tags"] is JArray rootTags)
            {
                tags = rootTags;
            }
            // 尝试从 OpenAPI 3.x 的 components 中获取
            else if (_swaggerData["components"]?["tags"] is JArray componentsTags)
            {
                tags = componentsTags;
            }
            // 尝试从 Swagger 2.0 的 definitions 中获取
            else if (_swaggerData["definitions"]?["tags"] is JArray definitionsTags)
            {
                tags = definitionsTags;
            }
            // 尝试从 paths 中收集所有标签
            else
            {
                var allTags = new HashSet<string>();

                foreach (var path in paths.Properties())
                {
                    var pathItem = (JObject)path.Value;
                    foreach (var method in pathItem.Properties())
                    {
                        if (method.Name == "summary" || method.Name == "description")
                            continue;

                        var operation = (JObject)method.Value;
                        var operationTags = operation["tags"] as JArray;

                        if (operationTags != null)
                        {
                            foreach (var tag in operationTags)
                            {
                                allTags.Add(tag.ToString());
                            }
                        }
                    }
                }

                // 将收集到的标签转换为 JArray
                tags = new JArray(allTags.Select(t => new JObject { ["name"] = t }));
            }

            // 创建标签节点
            if (tags != null && tags.Count > 0)
            {
                foreach (var tag in tags)
                {
                    string tagName = tag["name"]?.ToString();
                    string tagDescription = tag["description"]?.ToString() ?? tagName;

                    if (!string.IsNullOrEmpty(tagName))
                    {
                        var tagNode = new TreeNode(tagDescription)
                        {
                            Tag = new TagNodeData { TagName = tagName },
                            ImageIndex = 0,
                            SelectedImageIndex = 0
                        };
                        tagGroups[tagName] = tagNode;
                        treeEndpoints.Nodes.Add(tagNode);
                    }
                }
            }

            // 创建"未分组"节点
            var uncategorizedNode = new TreeNode("未分组")
            {
                Tag = new TagNodeData { TagName = "未分组" },
                ImageIndex = 0,
                SelectedImageIndex = 0
            };
            treeEndpoints.Nodes.Add(uncategorizedNode);

            // 遍历所有API端点
            foreach (var path in paths.Properties())
            {
                string pathName = path.Name;
                var pathItem = (JObject)path.Value;

                // 遍历该路径的所有HTTP方法
                foreach (var method in pathItem.Properties())
                {
                    if (method.Name == "summary" || method.Name == "description")
                        continue;

                    string methodName = method.Name.ToUpper();
                    var operation = (JObject)method.Value;

                    // 获取方法描述
                    string methodSummary = operation["summary"]?.ToString() ??
                                         operation["description"]?.ToString() ??
                                         $"{methodName} {pathName}";

                    // 创建方法节点
                    var methodNode = new TreeNode($"{methodName} -{pathName} ({methodSummary})")
                    {
                        Tag = new OperationNodeData
                        {
                            Path = pathName,
                            HttpMethod = method.Name,
                            Operation = operation
                        },
                        Checked = false,
                        ToolTipText = $"方法: {methodName} {pathName}"
                    };

                    // 设置节点颜色
                    methodNode.BackColor = GetMethodColor(methodName);

                    // 查找所属标签
                    var operationTags = operation["tags"] as JArray;
                    TreeNode parentNode = uncategorizedNode;

                    if (operationTags != null && operationTags.Count > 0)
                    {
                        string firstTag = operationTags[0].ToString();
                        if (tagGroups.ContainsKey(firstTag))
                        {
                            parentNode = tagGroups[firstTag];
                        }
                    }

                    // 添加到对应的标签节点
                    parentNode.Nodes.Add(methodNode);
                }
            }

            // 移除空的标签节点
            for (int i = treeEndpoints.Nodes.Count - 1; i >= 0; i--)
            {
                if (treeEndpoints.Nodes[i].Nodes.Count == 0 &&
                    treeEndpoints.Nodes[i].Tag is TagNodeData tagData &&
                    tagData.TagName != "未分组")
                {
                    treeEndpoints.Nodes.RemoveAt(i);
                }
            }
        }

        // 标签节点数据结构
        public class TagNodeData
        {
            public string TagName { get; set; }
        }

        // 方法节点数据结构保持不变
        public class OperationNodeData
        {
            public string Path { get; set; }
            public string HttpMethod { get; set; }
            public JObject Operation { get; set; }
        }

        private Color GetMethodColor(string methodName)
        {
            return methodName.ToUpper() switch
            {
                "GET" => Color.LightCyan,
                "POST" => Color.LightGreen,
                "PUT" => Color.LightGoldenrodYellow,
                "DELETE" => Color.LightPink,
                "PATCH" => Color.LightBlue,
                "HEAD" => Color.LightSeaGreen,
                _ => Color.LightGray
            };
        }

        #region 生成报告
        private void btnGenerate_Click(object sender, EventArgs e)
        {
            txtOutput.Clear();
            var output = new StringBuilder();
            output.AppendLine($"// API 接口定义 - {DateTime.Now:yyyy-MM-dd HH:mm}");
            output.AppendLine($"// 来源: {txtUrl.Text}");
            output.AppendLine("=".PadRight(80, '='));
            output.AppendLine();

            var generatedInterfaces = new HashSet<string>();
            bool hasCheckedNodes = false;

            // 遍历所有标签节点
            foreach (TreeNode tagNode in treeEndpoints.Nodes)
            {
                if (tagNode.Tag is TagNodeData tagData)
                {
                    foreach (TreeNode methodNode in tagNode.Nodes)
                    {
                        if (!methodNode.Checked) continue;

                        hasCheckedNodes = true;

                        if (methodNode.Tag is OperationNodeData methodData)
                        {
                            // 生成接口和方法
                            output.Append(
                                GenerateTypeScriptReport(methodData, generatedInterfaces)
                            );
                        }
                    }
                }
            }

            if (!hasCheckedNodes)
            {
                output.AppendLine("// 未选择任何端点");
            }

            txtOutput.Text = output.ToString();
        }

        private string GenerateTypeScriptReport(OperationNodeData methodData, HashSet<string> generatedInterfaces)
        {
            var output = new StringBuilder();
            var operation = methodData.Operation;
            string httpMethod = methodData.HttpMethod.ToLower();
            string path = methodData.Path;

            // 获取方法名（路径的最后一部分）
            string methodName = GetMethodNameFromPath(path);

            // 获取接口说明
            string methodSummary = operation["summary"]?.ToString() ??
                                 operation["description"]?.ToString() ??
                                 path;

            bool isPageList = false;
            if (methodName.Contains("PageList") || methodName.Contains("Page") || methodName.Contains("Export"))
            {
                isPageList = true;
            }
            // 生成接口名称
            string interfaceName = $"{methodName}Params";

            // 确保接口名唯一
            int counter = 1;
            string originalName = interfaceName;
            while (generatedInterfaces.Contains(interfaceName))
            {
                interfaceName = $"{originalName}{counter++}";
            }
            generatedInterfaces.Add(interfaceName);

            // 1. 生成接口定义
            if (!isPageList)
            {
                output.AppendLine($"interface {interfaceName} {{");
                GenerateInterfaceProperties(output, operation);
                output.AppendLine("}");
                output.AppendLine();
            }

            // 2. 生成请求方法
            output.AppendLine($"// {methodSummary}");
            if (isPageList)
            {
                output.AppendLine($"static {methodName}(params?: PageParams) {{");
                output.AppendLine($"  return request.{httpMethod}<PaginationResponse<any>>({{");
            }
            else
            {
                output.AppendLine($"static {methodName}(params?: {interfaceName}) {{");
                output.AppendLine($"  return request.{httpMethod}<BaseResponse<any>>({{");
            }
            output.AppendLine($"    url: '{path}',");
            output.AppendLine("    params");
            output.AppendLine("  })");
            output.AppendLine("}");
            output.AppendLine();

            return output.ToString();
        }

        private string GetMethodNameFromPath(string path)
        {
            // 获取路径的最后一部分作为方法名
            var segments = path.Split('/');
            string lastSegment = segments.LastOrDefault();

            if (string.IsNullOrEmpty(lastSegment)) return "UnnamedMethod";

            // 确保首字母大写
            return char.ToUpper(lastSegment[0]) + lastSegment.Substring(1);
        }

        private void GenerateInterfaceProperties(StringBuilder output, JObject operation)
        {
            bool hasProperties = false;

            // 处理OpenAPI 3.x请求体
            if (operation["requestBody"]?["content"] is JObject content)
            {
                // 只处理第一个媒体类型（通常是application/json）
                var mediaType = content.Properties().FirstOrDefault();
                if (mediaType != null)
                {
                    var schema = mediaType.Value?["schema"];
                    if (schema != null)
                    {
                        // 获取Body属性模式
                        var bodySchema = GetBodySchema(schema);
                        if (bodySchema != null)
                        {
                            GenerateProperties(output, bodySchema);
                            hasProperties = true;
                        }
                    }
                }
            }

            // 处理Swagger 2.0请求体（body参数）
            if (!hasProperties && operation["parameters"] is JArray parameters)
            {
                var bodyParams = parameters.Where(p => p["in"]?.ToString() == "body").ToList();
                if (bodyParams.Count > 0)
                {
                    foreach (var param in bodyParams)
                    {
                        var schema = param["schema"];
                        if (schema != null)
                        {
                            // 获取Body属性模式
                            var bodySchema = GetBodySchema(schema);
                            if (bodySchema != null)
                            {
                                GenerateProperties(output, bodySchema);
                                hasProperties = true;
                            }
                        }
                    }
                }
            }

            // 如果没有属性，添加注释说明
            if (!hasProperties)
            {
                output.AppendLine("  // 无参数定义");
            }
        }

        private JToken GetBodySchema(JToken schema)
        {
            // 处理引用类型
            if (schema["$ref"] != null)
            {
                schema = ResolveReference(schema["$ref"].ToString());
            }

            // 直接查找Body属性
            if (schema["properties"] is JObject properties && properties["Body"] != null)
            {
                var bodyProp = properties["Body"];
                if (bodyProp["$ref"] != null)
                {
                    return ResolveReference(bodyProp["$ref"].ToString());
                }
                return bodyProp;
            }

            // 如果没有Body属性，返回整个schema
            return schema;
        }

        private void GenerateProperties(StringBuilder output, JToken bodySchema)
        {
            JToken properties = null;

            // 处理引用类型
            if (bodySchema["$ref"] != null)
            {
                var refSchema = ResolveReference(bodySchema["$ref"].ToString());
                properties = refSchema["properties"];
            }
            else if (bodySchema["properties"] != null)
            {
                properties = bodySchema["properties"];
            }

            if (properties == null || !(properties is JObject props))
            {
                output.AppendLine("  // 未定义属性");
                return;
            }

            foreach (var prop in props.Properties())
            {
                var propName = prop.Name;
                var propInfo = (JObject)prop.Value;

                // 获取类型信息
                var type = GetTypeScriptType(propInfo);
                var description = propInfo["description"]?.ToString() ?? string.Empty;
                var required = propInfo["required"]?.ToString() == "true";

                output.Append($"  {propName}");
                //if (!required) output.Append("?");
                output.Append($": {type}");

                //if (!string.IsNullOrEmpty(description))
                //{
                //    output.Append($" // {description}");
                //}

                output.AppendLine();
            }
        }

        private string GetTypeScriptType(JObject schema)
        {
            if (schema == null) return "any";

            // 处理引用类型
            if (schema["$ref"] != null)
            {
                return GetReferenceName(schema["$ref"].ToString());
            }

            // 处理数组类型
            if (schema["type"]?.ToString() == "array")
            {
                var items = schema["items"];
                if (items != null)
                {
                    var itemsRef = items["$ref"]?.ToString();
                    if (itemsRef != null)
                    {
                        return $"{GetReferenceName(itemsRef)}[]";
                    }
                    return $"{GetTypeScriptType(items as JObject)}[]";
                }
                return "any[]";
            }

            // 获取基本类型
            var type = schema["type"]?.ToString() ?? "object";
            var format = schema["format"]?.ToString();

            // 处理枚举类型
            if (schema["enum"] != null)
            {
                return "string";
            }

            // 根据类型和格式映射到TypeScript类型
            return (type, format) switch
            {
                ("integer", _) => "number",
                ("number", _) => "number",
                ("string", "date-time") => "string",
                ("string", "uuid") => "string",
                ("string", "binary") => "string",
                ("boolean", _) => "boolean",
                ("string", _) => "string",
                ("object", _) => "object",
                _ => "any"
            };
        }

        private string GetReferenceName(string refPath)
        {
            if (string.IsNullOrEmpty(refPath))
                return "unknown";

            // 提取引用类型名：获取最后一个路径片段
            var segments = refPath.Split('/');
            for (int i = segments.Length - 1; i >= 0; i--)
            {
                if (!string.IsNullOrEmpty(segments[i]) && segments[i] != "#")
                {
                    return segments[i];
                }
            }

            return "unknown";
        }

        private JToken ResolveReference(string refPath)
        {
            // 只处理内部引用（以#开头）
            if (string.IsNullOrEmpty(refPath) || !refPath.StartsWith("#/"))
            {
                Debug.WriteLine($"无法解析外部引用: {refPath}");
                return new JObject();
            }

            // 去掉开头的'#'并分割路径
            var path = refPath.TrimStart('#').Split('/');
            JToken current = _swaggerData;

            foreach (var segment in path)
            {
                if (string.IsNullOrEmpty(segment) || segment == "#")
                    continue;

                current = current?[segment];
                if (current == null)
                {
                    Debug.WriteLine($"引用解析失败: 在路径 '{segment}' 处中断，完整路径: {refPath}");
                    return new JObject();
                }
            }

            return current;
        }
        #endregion

        private void treeEndpoints_AfterCheck(object sender, TreeViewEventArgs e)
        {
            // 防止递归触发
            if (e.Action != TreeViewAction.ByMouse && e.Action != TreeViewAction.ByKeyboard)
                return;

            // 更新父子节点勾选状态
            UpdateParentChildLinkState(e.Node);
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtOutput.Text))
            {
                Clipboard.SetText(txtOutput.Text);
                lblStatus.Text = "结果已复制到剪贴板";
            }
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtOutput.Text))
            {
                MessageBox.Show("没有内容可导出", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            using (var saveDialog = new SaveFileDialog())
            {
                saveDialog.Filter = "文本文件|*.txt|Markdown文件|*.md";
                saveDialog.Title = "导出参数报告";
                saveDialog.FileName = $"Swagger参数报告_{DateTime.Now:yyyyMMddHHmm}.md";

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        File.WriteAllText(saveDialog.FileName, txtOutput.Text);
                        MessageBox.Show("导出成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        // 打开导出目录
                        Process.Start("explorer.exe", $"/select,\"{saveDialog.FileName}\"");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"导出失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void btnExpandAll_Click(object sender, EventArgs e)
        {
            treeEndpoints.ExpandAll();
        }

        private void btnCollapseAll_Click(object sender, EventArgs e)
        {
            treeEndpoints.CollapseAll();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            SearchTreeView(txtSearch.Text.Trim());
        }

        private void btnSearchPrev_Click(object sender, EventArgs e)
        {
            if (_searchResults.Count == 0) return;

            int newIndex = (_currentSearchIndex - 1 + _searchResults.Count) % _searchResults.Count;
            NavigateToSearchResult(newIndex);
        }

        private void btnSearchNext_Click(object sender, EventArgs e)
        {
            if (_searchResults.Count == 0) return;

            int newIndex = (_currentSearchIndex + 1) % _searchResults.Count;
            NavigateToSearchResult(newIndex);
        }

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SearchTreeView(txtSearch.Text.Trim());
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.F3)
            {
                if (string.IsNullOrWhiteSpace(_lastSearchTerm) || txtSearch.Text != _lastSearchTerm)
                {
                    SearchTreeView(txtSearch.Text.Trim());
                }
                else if (_searchResults.Count > 0)
                {
                    btnSearchNext_Click(sender, e);
                }
                e.Handled = true;
            }
        }

        #region 搜索功能
        private void SearchTreeView(string searchTerm)
        {
            // 清除之前的高亮
            ClearHighlight();

            // 如果搜索词为空，则重置搜索状态
            if (string.IsNullOrWhiteSpace(searchTerm))
            {
                _searchResults.Clear();
                _currentSearchIndex = -1;
                btnSearchPrev.Enabled = false;
                btnSearchNext.Enabled = false;
                return;
            }

            _searchResults.Clear();
            _currentSearchIndex = -1;

            // 执行搜索
            SearchNodes(treeEndpoints.Nodes, searchTerm);
            _lastSearchTerm = searchTerm;

            // 更新导航按钮状态
            UpdateSearchNavButtons();

            // 如果找到结果，定位到第一个
            if (_searchResults.Count > 0)
            {
                NavigateToSearchResult(0);
            }
            else
            {
                lblStatus.Text = $"未找到包含'{searchTerm}'的节点";
            }
        }

        private void SearchNodes(TreeNodeCollection nodes, string searchTerm)
        {
            foreach (TreeNode node in nodes)
            {
                // 检查当前节点是否匹配
                if (node.Text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    _searchResults.Add(node);
                }

                // 递归搜索子节点
                if (node.Nodes.Count > 0)
                {
                    SearchNodes(node.Nodes, searchTerm);
                }
            }
        }

        private void NavigateToSearchResult(int index)
        {
            if (index < 0 || index >= _searchResults.Count)
                return;

            _currentSearchIndex = index;

            // 高亮显示当前搜索结果
            var resultNode = _searchResults[index];
            resultNode.BackColor = Color.FromArgb(255, 255, 200); // 淡黄色高亮
            resultNode.ForeColor = Color.Black;

            // 确保节点可见
            resultNode.EnsureVisible();

            // 选中该节点
            treeEndpoints.SelectedNode = resultNode;
            treeEndpoints.Focus();

            // 更新状态
            lblStatus.Text = $"找到 {_searchResults.Count} 个结果 ({_currentSearchIndex + 1}/{_searchResults.Count})";

            // 更新导航按钮状态
            UpdateSearchNavButtons();
        }

        private void UpdateSearchNavButtons()
        {
            btnSearchPrev.Enabled = _searchResults.Count > 1;
            btnSearchNext.Enabled = _searchResults.Count > 1;
        }

        private void ClearHighlight()
        {
            // 重置所有节点颜色
            ResetNodeColors(treeEndpoints.Nodes);

            // 清除搜索状态
            _currentSearchIndex = -1;
            _searchResults.Clear();
            lblStatus.Text = "就绪";
        }

        private void ResetNodeColors(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                // 重置节点颜色
                if (node.Level == 0) // 路径节点
                {
                    node.BackColor = treeEndpoints.BackColor;
                    node.ForeColor = Color.Black;
                }
                else // 方法节点
                {
                    node.BackColor = GetMethodColor(node.Text.Split('-')[0].Trim().ToUpper());
                    node.ForeColor = Color.Black;
                }

                // 递归重置子节点
                if (node.Nodes.Count > 0)
                {
                    ResetNodeColors(node.Nodes);
                }
            }
        }
        #endregion

        #region 取消全选功能
        private void btnUncheckAll_Click(object sender, EventArgs e)
        {
            // 递归取消所有节点的勾选
            UncheckAllNodes(treeEndpoints.Nodes);
        }

        private void UncheckAllNodes(TreeNodeCollection nodes)
        {
            // 暂时禁用事件以防递归
            treeEndpoints.AfterCheck -= treeEndpoints_AfterCheck;

            foreach (TreeNode node in nodes)
            {
                node.Checked = false;
                if (node.Nodes.Count > 0)
                {
                    UncheckAllNodes(node.Nodes);
                }
            }

            // 重新启用事件
            treeEndpoints.AfterCheck += treeEndpoints_AfterCheck;
        }
        #endregion

        #region 父子节点勾选联动
        private void UpdateParentChildLinkState(TreeNode node)
        {
            // 只处理父节点（标签节点）的勾选状态变化
            if (node.Level == 0) // 标签节点
            {
                // 当父节点被勾选时，自动勾选所有子节点
                if (node.Checked)
                {
                    // 暂时禁用事件以防递归
                    treeEndpoints.AfterCheck -= treeEndpoints_AfterCheck;

                    foreach (TreeNode child in node.Nodes)
                    {
                        child.Checked = true;
                    }

                    // 重新启用事件
                    treeEndpoints.AfterCheck += treeEndpoints_AfterCheck;
                }
                // 当父节点取消勾选时，自动取消所有子节点的勾选
                else
                {
                    // 暂时禁用事件以防递归
                    treeEndpoints.AfterCheck -= treeEndpoints_AfterCheck;

                    foreach (TreeNode child in node.Nodes)
                    {
                        child.Checked = false;
                    }

                    // 重新启用事件
                    treeEndpoints.AfterCheck += treeEndpoints_AfterCheck;
                }
            }
            // 处理子节点（方法节点）的勾选状态变化
            else if (node.Level == 1) // 方法节点
            {
                // 当子节点状态改变时，更新父节点状态
                if (node.Parent != null)
                {
                    // 检查是否所有子节点都被勾选
                    bool allChecked = true;
                    bool anyChecked = false;

                    foreach (TreeNode sibling in node.Parent.Nodes)
                    {
                        if (sibling.Checked)
                        {
                            anyChecked = true;
                        }
                        else
                        {
                            allChecked = false;
                        }
                    }

                    // 暂时禁用事件以防递归
                    treeEndpoints.AfterCheck -= treeEndpoints_AfterCheck;

                    // 更新父节点状态
                    if (allChecked)
                    {
                        node.Parent.Checked = true;
                    }
                    else if (anyChecked)
                    {
                        // 部分勾选状态（使用特殊图标或样式）
                        node.Parent.Checked = false;
                        // 可以在这里添加部分勾选的视觉指示
                    }
                    else
                    {
                        node.Parent.Checked = false;
                    }

                    // 重新启用事件
                    treeEndpoints.AfterCheck += treeEndpoints_AfterCheck;
                }
            }
        }
        #endregion

        #endregion

        #region tab2 单号格式转换

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtInputCode.Clear();
            txtOutputCode.Clear();
            lblStatus.Text = "就绪";
        }

        private void btnConvert_Click(object sender, EventArgs e)
        {
            string input = txtInputCode.Text;
            string formatted = FormatNumbers(input);

            txtOutputCode.Text = formatted;

            // 自动复制到剪贴板
            if (!string.IsNullOrEmpty(formatted))
            {
                Clipboard.SetText(formatted);
                lblStatus.Text = "结果已复制到剪贴板！";
            }
        }

        private void btnCopyCode_Click(object sender, EventArgs e)
        {
            string input = txtInputCode.Text;
            string formatted = FormatNumbers(input);

            txtOutputCode.Text = formatted;

            // 自动复制到剪贴板
            if (!string.IsNullOrEmpty(formatted))
            {
                Clipboard.SetText(formatted);
                lblStatus.Text = "结果已复制到剪贴板！";
            }
        }

        /// <summary>
        /// 转换格式
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private string FormatNumbers(string input)
        {
            // 获取用户指定的分隔符
            string delimiter = delimiter = ",;、， \t\n\r";

            // 创建分隔符数组
            char[] delimiters = delimiter.ToCharArray();

            // 分割输入
            string[] items = input.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

            if (items.Length == 0)
                return string.Empty;

            StringBuilder sb = new StringBuilder();
            foreach (string item in items)
            {
                // 清理每个项目（移除首尾空白）
                string cleanItem = item.Trim();

                if (string.IsNullOrEmpty(cleanItem))
                    continue;

                if (sb.Length > 0)
                    sb.Append(",");
                if (ck_ID.Checked)
                {
                    sb.AppendFormat("{0}", cleanItem);
                }
                else
                {
                    sb.AppendFormat("'{0}'", cleanItem);
                }
            }

            return sb.ToString();
        }
        #endregion

        private void btn_Fomart_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txt_oneFomart.Text) && !string.IsNullOrWhiteSpace(txt_FomartMode.Text))
            {
                string strMode = txt_FomartMode.Text.Trim();
                string sbStr = null;
                string[] CodeStr = txt_oneFomart.Lines;
                List<string> CodeList = new List<string>();
                foreach (string item in CodeStr)
                {
                    if (!string.IsNullOrWhiteSpace(item.Trim()))
                    {
                        CodeList.Add(item);
                    }
                }
                for (int i = 0; i < CodeList.Count; i++)
                {
                    sbStr += strMode.Replace("@@", CodeList[i].Trim()) + "\r\n";
                }

                if (!string.IsNullOrWhiteSpace(sbStr))
                {
                    this.txt_AllFomart.Text = sbStr;
                    this.txt_AllFomart.Focus();
                    this.txt_AllFomart.SelectAll();
                }
            }
        }
    }

    public class OperationNodeData
    {
        public string Path { get; set; }
        public string HttpMethod { get; set; }
        public JObject Operation { get; set; }
    }
}